/*!
    \copyright  Copyright (c) 2022 - 2025 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \ingroup    le_audio_client
    \brief    Table and interface function used LE Audio Client Config
*/

#include "le_audio_client_audio_config.h"
#include "le_audio_client_broadcast_private.h"
#include "le_audio_client_unicast_private.h"
#include "logging.h"
#include "kymera.h"
#include <panic.h>

#ifdef INCLUDE_LE_AUDIO_BROADCAST_SOURCE

/*! Structure to hold broadcast audio configuration */
le_audio_client_audio_broadcast_config_t lea_client_bcast_config;

#endif /* INCLUDE_LE_AUDIO_BROADCAST_SOURCE */

#if defined(INCLUDE_LE_AUDIO_BROADCAST_SOURCE)

static const le_audio_client_config_interface_t *le_audio_config_callback_configs = NULL;

#endif /* defined(INCLUDE_LE_AUDIO_BROADCAST_SOURCE) */

#ifdef INCLUDE_LE_AUDIO_UNICAST_SOURCE

/*! As per QBCE Spec(section 5.7.97), the PHY for Q2Q should be 0x80 */
#define LE_AUDIO_CLIENT_Q2Q_PHY                   (0x80)

/*! RTN from Central to Peripheral value for aptX Adaptive */
#define LE_AUDIO_CLIENT_RTN_APTX_ADAPTIVE_C_TO_P  (0xf)

/*! RTN from Central to Peripheral value for Gaming without VBC */
#define LE_AUDIO_CLIENT_RTN_GAME_NO_VBC_C_TO_P    (0x5)

/*! RTN from Central to Peripheral value for Gaming with VBC */
#define LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_C_TO_P  (0x3)

/*! RTN from Peripheral to Central value for Gaming with VBC */
#define LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_P_TO_C  (0x3)

/*! RTN from Central to Peripheral value for Gaming without VBC */
#define LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_NO_VBC_C_TO_P    (0x3)

/*! RTN from Central to Peripheral value for Gaming with VBC */
#define LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_WITH_VBC_C_TO_P  (0x3)

/*! RTN from Peripheral to Central value for Gaming with VBC */
#define LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_WITH_VBC_P_TO_C  (0x7)

/*! Audio Config for gaming */
le_audio_client_audio_config_t  le_audio_client_audio_config_gaming =
{
    .target_latency             = CAP_CLIENT_TARGET_LOWER_LATENCY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_48_1,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_RTN_GAME_NO_VBC_C_TO_P,
    .rtn_ptoc                   = 0x0
};

/*! Audio Config for gaming with VBC */
le_audio_client_audio_config_t  le_audio_client_audio_config_gaming_with_vbc =
{
    .target_latency             = CAP_CLIENT_TARGET_LOWER_LATENCY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_48_1,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_16_1,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_C_TO_P,
    .rtn_ptoc                   = LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_P_TO_C
};

/*! Audio Config for media usecase */
le_audio_client_audio_config_t  le_audio_client_audio_config_media =
{
    .target_latency             = CAP_CLIENT_TARGET_HIGH_RELIABILITY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_48_2,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_RTN_GAME_NO_VBC_C_TO_P,
    .rtn_ptoc                   = 0x0
};

#ifdef INCLUDE_LE_APTX_ADAPTIVE
/*! QHS MAP table for LE aptX Adaptive media usecase */
const QCOM_CON_MANAGER_CIS_QHS_PARAMS_T aptx_adaptive_cis_qhs_map[QCOM_MAX_NUM_OF_QHS_RATE] =
{
    /* bn_c_to_p    bn_p_to_c     max_pdu_c_to_p     max_pdu_p_to_c */
    {0,             0,            0,                 0               },    /* QHS6 */
    {0,             0,            0,                 0               },    /* QHS5 */
    {2,             2,            608,               0               },    /* QHS4 */
    {1,             1,            452,               0               },    /* QHS3 */
    {1,             1,            300,               0               }     /* QHS2 */
};

/*! Audio Config for LE aptX Adaptive media usecase */
le_audio_client_audio_config_t  le_audio_client_audio_config_aptx_adaptive_media =
{
    .target_latency             = CAP_CLIENT_TARGET_HIGH_RELIABILITY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_APTX_ADAPTIVE_48_1,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_RTN_APTX_ADAPTIVE_C_TO_P,
    .rtn_ptoc                   = 0x0
};
#endif /* INCLUDE_LE_APTX_ADAPTIVE */

/*! Audio Config for conversational usecase */
le_audio_client_audio_config_t  le_audio_client_audio_config_conversational =
{
    .target_latency             = CAP_CLIENT_TARGET_BALANCE_LATENCY_AND_RELIABILITY,
    .sink_stream_capability     = TMAP_CLIENT_STREAM_CAPABILITY_32_2,
    .source_stream_capability   = TMAP_CLIENT_STREAM_CAPABILITY_32_2,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_C_TO_P,
    .rtn_ptoc                   = LE_AUDIO_CLIENT_RTN_GAME_WITH_VBC_P_TO_C
};

#ifdef INCLUDE_LE_AUDIO_GAMING_MODE_APTX_LITE
/*! Audio Config for gaming using VS Aptx Lite */
le_audio_client_audio_config_t  le_audio_client_audio_config_gaming_aptx_lite =
{
    .target_latency             = CAP_CLIENT_TARGET_LOWER_LATENCY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_APTX_LITE_48_1,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_NO_VBC_C_TO_P,
    .rtn_ptoc                   = 0x0
};

/*! Audio Config for gaming with VBC using VS Aptx Lite */
le_audio_client_audio_config_t  le_audio_client_audio_config_gaming_with_vbc_aptx_lite =
{
    .target_latency             = CAP_CLIENT_TARGET_LOWER_LATENCY,
    .sink_stream_capability     = CAP_CLIENT_STREAM_CAPABILITY_APTX_LITE_48_1,
    .source_stream_capability   = CAP_CLIENT_STREAM_CAPABILITY_APTX_LITE_16_1 ,
    .framing                    = LE_AUDIO_CLIENT_UNFRAMED,
    .phy_ctop                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .phy_ptoc                   = LE_AUDIO_CLIENT_Q2Q_PHY,
    .rtn_ctop                   = LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_WITH_VBC_C_TO_P,
    .rtn_ptoc                   = LE_AUDIO_CLIENT_APTX_LITE_RTN_GAME_WITH_VBC_P_TO_C
};

#endif /* INCLUDE_LE_AUDIO_GAMING_MODE_APTX_LITE */

/* Audio config with default configuration(like stream cap) overridden by that supported on remote/sink device */
le_audio_client_audio_config_t le_audio_client_audio_config_remote_capabilities = {0};

static CapClientSreamCapability leAudioClient_GetNextRemoteSupportedStreamCapability(ServiceHandle group_handle,
                                                                                     CapClientContext audio_context,
                                                                                     CapClientSreamCapability current_stream_capability,
                                                                                     CapClientAseType ase_type)
{
    if (current_stream_capability != CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN)
    {
        /* Check if any of the next stream capabilities is supported by remote & consider that for configuration */
        while (current_stream_capability >>= 1)
        {
            if (CapProfileClient_CheckIfRemoteSupports(group_handle,
                                                       audio_context,
                                                       current_stream_capability,
                                                       ase_type))
            {
                break;
            }
        }
    }

    DEBUG_LOG("leAudioClient_GetNextRemoteSupportedStreamCapability remote supported stream_capability 0x%x,"
              "audio context = 0x%x, ase_type = %d", current_stream_capability, audio_context, ase_type);

    return current_stream_capability;
}

static bool leAudioClient_UpdateRemoteSupportedAudioConfig(ServiceHandle group_handle,
                                                           CapClientContext audio_context,
                                                           le_audio_client_audio_config_t* audio_config,
                                                           CapClientAseType ase_type)
{
    bool is_audio_config_updated = FALSE;
    CapClientSreamCapability stream_capability = ase_type == CAP_CLIENT_ASE_SINK ? audio_config->sink_stream_capability :
                                                                                   audio_config->source_stream_capability;

    /* Get the next remote supported stream capability for that specific audio context */
    stream_capability = leAudioClient_GetNextRemoteSupportedStreamCapability(group_handle,
                                                                             audio_context,
                                                                             stream_capability,
                                                                             ase_type);

    /* Update the remote supported audio config with stream capability supported on remote only if it is valid.
     * If it is unknown then, either none of the stream capabilities are supported for specified context/ase_type or
     * audio context itself is not supported and in that case remote supported audio config is not updated. */
    if (stream_capability != CAP_CLIENT_STREAM_CAPABILITY_UNKNOWN)
    {
        if (ase_type == CAP_CLIENT_ASE_SINK)
        {
            le_audio_client_audio_config_remote_capabilities.sink_stream_capability = stream_capability;
        }
        else
        {
            le_audio_client_audio_config_remote_capabilities.source_stream_capability = stream_capability;
        }
        is_audio_config_updated = TRUE;
    }

    return is_audio_config_updated;
}

static bool leAudioClient_CheckIfPreferredConfigNeedsToBeOverridden(ServiceHandle group_handle,
                                                                    CapClientContext audio_context,
                                                                    le_audio_client_audio_config_t* preferred_audio_config)
{
    bool override_audio_config = FALSE;
    /* As Gaming with VBC is not standard audio context as per spec, gaming context would be checked in this case */
    CapClientContext audio_context_to_check = audio_context == CAP_CLIENT_CONTEXT_TYPE_GAME_WITH_VBC ?
                                              CAP_CLIENT_CONTEXT_TYPE_GAME : audio_context;

    /* Copy the current default audio config into remote supported audio config */
    memcpy(&le_audio_client_audio_config_remote_capabilities,
           preferred_audio_config,
           sizeof (le_audio_client_audio_config_t));

    /* Check if remote supports the default sink stream capability and update the remote supported audio config
     * with sink stream capability supported on remote(if valid) only in case of LC3 codec(standard) */
    if (!CapProfileClient_CheckIfRemoteSupports(group_handle,
                                                audio_context_to_check,
                                                preferred_audio_config->sink_stream_capability,
                                                CAP_CLIENT_ASE_SINK))
    {
        override_audio_config = leAudioClient_UpdateRemoteSupportedAudioConfig(group_handle,
                                                                               audio_context_to_check,
                                                                               preferred_audio_config,
                                                                               CAP_CLIENT_ASE_SINK);
    }

    /* Check if remote supports the default source stream capability and update the remote supported audio config
     * with source stream capability supported on remote(if valid) only in case of LC3 codec(standard) and scenarios
     * with mic involved at sink */
    if ((audio_context & (CAP_CLIENT_CONTEXT_TYPE_CONVERSATIONAL | CAP_CLIENT_CONTEXT_TYPE_GAME_WITH_VBC)) &&
        !CapProfileClient_CheckIfRemoteSupports(group_handle,
                                                audio_context_to_check,
                                                preferred_audio_config->source_stream_capability,
                                                CAP_CLIENT_ASE_SOURCE))
    {
        override_audio_config = leAudioClient_UpdateRemoteSupportedAudioConfig(group_handle,
                                                                               audio_context_to_check,
                                                                               preferred_audio_config,
                                                                               CAP_CLIENT_ASE_SOURCE);
    }

    return override_audio_config;
}

const le_audio_client_audio_config_t* leAudioClient_GetAudioConfig(ServiceHandle group_handle,
                                                                   CapClientContext audio_context,
                                                                   uint8 codec)
{
    le_audio_client_audio_config_t *audio_configuration = NULL;

#ifndef INCLUDE_LE_AUDIO_GAMING_MODE_APTX_LITE
    UNUSED(codec);
#endif

    switch (audio_context)
    {
        case CAP_CLIENT_CONTEXT_TYPE_GAME:
#ifdef INCLUDE_LE_AUDIO_GAMING_MODE_APTX_LITE
            audio_configuration = codec == KYMERA_LE_AUDIO_CODEC_APTX_LITE ? &le_audio_client_audio_config_gaming_aptx_lite : &le_audio_client_audio_config_gaming;
#else
            audio_configuration = &le_audio_client_audio_config_gaming;
#endif
        break;

        case CAP_CLIENT_CONTEXT_TYPE_GAME_WITH_VBC:
#ifdef INCLUDE_LE_AUDIO_GAMING_MODE_APTX_LITE
            audio_configuration = codec == KYMERA_LE_AUDIO_CODEC_APTX_LITE ? &le_audio_client_audio_config_gaming_with_vbc_aptx_lite : &le_audio_client_audio_config_gaming_with_vbc;
#else
            audio_configuration = &le_audio_client_audio_config_gaming_with_vbc;
#endif
        break;

        case CAP_CLIENT_CONTEXT_TYPE_MEDIA:
#ifdef INCLUDE_LE_APTX_ADAPTIVE
            audio_configuration = codec == KYMERA_LE_AUDIO_CODEC_APTX_ADAPTIVE ? &le_audio_client_audio_config_aptx_adaptive_media : &le_audio_client_audio_config_media;
#else
            audio_configuration = &le_audio_client_audio_config_media;
#endif
        break;

        case CAP_CLIENT_CONTEXT_TYPE_CONVERSATIONAL:
            audio_configuration = &le_audio_client_audio_config_conversational;
        break;

        default:
        break;
    }

    if (codec == KYMERA_LE_AUDIO_CODEC_LC3)
    {
        /* For LC3, compare the preferred audio config against the remote supported audio config and if required,
         * override the preferred config with that of remote config.(only if config is valid) */
        if (leAudioClient_CheckIfPreferredConfigNeedsToBeOverridden(group_handle, audio_context, audio_configuration))
        {
            audio_configuration = &le_audio_client_audio_config_remote_capabilities;
        }
    }

    return audio_configuration;
}

#endif /* INCLUDE_LE_AUDIO_UNICAST_SOURCE */

#if defined(INCLUDE_LE_AUDIO_UNICAST_SOURCE) || defined(INCLUDE_LE_AUDIO_BROADCAST_SOURCE)

void leAudioClient_AudioConfigInit(void)
{
#ifdef INCLUDE_LE_AUDIO_BROADCAST_SOURCE
    lea_client_bcast_config.sub_group_info = (CapClientBigSubGroups*) PanicUnlessMalloc(sizeof(CapClientBigSubGroups));
    lea_client_bcast_config.sub_group_info->bisInfo = (CapClientBisInfo*) PanicUnlessMalloc(sizeof(CapClientBisInfo) * BAP_MAX_NUMBER_BIS);
#endif /* INCLUDE_LE_AUDIO_BROADCAST_SOURCE */
}

#endif /* defined(INCLUDE_LE_AUDIO_UNICAST_SOURCE) || defined(INCLUDE_LE_AUDIO_BROADCAST_SOURCE) */

#ifdef INCLUDE_LE_AUDIO_BROADCAST_SOURCE

static BapAudioLocation leAudioClient_GetAudioLocation(uint16 no_of_bis, uint16 no_of_audio_channels_per_bis, bool is_right)
{
    BapAudioLocation audio_location;

    if (no_of_bis == 2)
    {
        /* Dual BIS configuration */
        audio_location = is_right ? BAP_AUDIO_LOCATION_FR : BAP_AUDIO_LOCATION_FL;
    }
    else
    {
        /* Mono or Stereo BIS configuration */
        audio_location = (no_of_audio_channels_per_bis == 2) ? (BAP_AUDIO_LOCATION_FL | BAP_AUDIO_LOCATION_FR) : BAP_AUDIO_LOCATION_MONO;
    }

    return audio_location;
}

static void leAudioClient_SetBroadcastBisInfo(CapClientBigSubGroups *subgroup_info, LE_AUDIO_CLIENT_BROADCAST_CONFIG_T *bcast_config)
{
    uint16 i;

    subgroup_info->numBis = bcast_config->number_of_bis;

    for (i = 0; i < subgroup_info->numBis; i++)
    {
        /* bisInfo[0] is always for Audio location Left */
        subgroup_info->bisInfo[i].audioLocation = leAudioClient_GetAudioLocation(bcast_config->number_of_bis,
                                                                                 bcast_config->no_of_audio_channels_per_bis,
                                                                                 i != 0);
        subgroup_info->bisInfo[i].config = bcast_config->broadcast_stream_capability;
        subgroup_info->bisInfo[i].targetLatency = bcast_config->target_latency;
        subgroup_info->bisInfo[i].lc3BlocksPerSdu = LE_AUDIO_CLIENT_BROADCAST_LC3_BLOCKS_PER_SDU;
    }
}

static void leAudioClient_GetBcastConfig(le_audio_client_audio_broadcast_config_t *bcast_config)
{
    if (le_audio_config_callback_configs->GetBroadcastAudioConfigV2 != NULL)
    {
        le_audio_client_broadcast_config_v2_t *bcast_user_config;

        le_audio_config_callback_configs->GetBroadcastAudioConfigV2(&bcast_user_config);

        bcast_config->num_sub_group = bcast_user_config->number_of_sub_groups;
        bcast_config->broadcast_type = bcast_user_config->broadcast_type;
        bcast_config->presentation_delay = bcast_user_config->presentation_delay;
        bcast_config->broadcast_config_params = bcast_user_config->bcast_config;
        bcast_config->sub_group_info = bcast_user_config->sub_groups;

        DEBUG_LOG("leAudioClient_GetBcastConfig V2: number_of_sub_groups: %d presentation_delay: %d",
                    bcast_config->num_sub_group,
                    bcast_config->presentation_delay);
    }
    else
    {
        /* Version 1 for backward compatibility */
        LE_AUDIO_CLIENT_BROADCAST_CONFIG_T bcast_user_config;
        memset(&bcast_user_config, 0, sizeof(bcast_user_config));

        le_audio_config_callback_configs->GetBroadcastAudioConfig(&bcast_user_config);
        bcast_config->broadcast_type = bcast_user_config.broadcast_type;
        bcast_config->num_sub_group = LE_AUDIO_CLIENT_BROADCAST_NUM_SUB_GROUPS;
        bcast_config->presentation_delay = bcast_user_config.presentation_delay;
        bcast_config->sub_group_info->config = bcast_user_config.broadcast_stream_capability;
        bcast_config->sub_group_info->targetLatency = bcast_user_config.target_latency;
        bcast_config->sub_group_info->lc3BlocksPerSdu = LE_AUDIO_CLIENT_BROADCAST_LC3_BLOCKS_PER_SDU;
        bcast_config->sub_group_info->useCase = bcast_user_config.audio_context;
        bcast_config->sub_group_info->metadataLen = 0;
        bcast_config->sub_group_info->metadata = NULL;
        bcast_config->broadcast_config_params.rtn = bcast_user_config.rtn;
        bcast_config->broadcast_config_params.sduSize = bcast_user_config.sdu_size;
        bcast_config->broadcast_config_params.maxLatency = bcast_user_config.max_latency;
        bcast_config->broadcast_config_params.phy = bcast_user_config.phy;
        bcast_config->broadcast_config_params.sduInterval = bcast_user_config.sdu_interval;
        bcast_config->broadcast_config_params.streamCapability = bcast_user_config.broadcast_stream_capability;

        /* For now these parameters are not user configurable */
        bcast_config->broadcast_config_params.packing = 0; /* Sequential placement of packets */
        bcast_config->broadcast_config_params.framing = LE_AUDIO_CLIENT_UNFRAMED;
        bcast_config->broadcast_config_params.vsConfigLen = 0;
        bcast_config->broadcast_config_params.vsConfig = NULL;

        leAudioClient_SetBroadcastBisInfo(bcast_config->sub_group_info, &bcast_user_config);

        DEBUG_LOG("leAudioClient_GetBcastConfig V1: Stream config: 0x%x, targetLatency %d, useCase %d, name len %d, Encrypted %d",
                    bcast_user_config.broadcast_stream_capability,
                    bcast_user_config.target_latency,
                    bcast_user_config.audio_context,
                    bcast_config->broadcast_source_name_len,
                    bcast_config->broadcast_code != NULL);
        DEBUG_LOG("    rtn: 0x%x, sdu_size 0x%x, max_codec_frame_per_sdu 0x%x, max_latency 0x%x, phy: 0x%x, sdu_interval: 0x%x",
                    bcast_user_config.rtn,
                    bcast_user_config.sdu_size,
                    bcast_user_config.max_codec_frames_per_sdu,
                    bcast_user_config.max_latency,
                    bcast_user_config.phy,
                    bcast_user_config.sdu_interval);
    }
}

const le_audio_client_audio_broadcast_config_t* leAudioClient_GetBroadcastAudioConfig(void)
{
    le_audio_client_audio_broadcast_config_t *audio_configuration = &lea_client_bcast_config;
    LE_AUDIO_CLIENT_BROADCAST_NAME_CODE_T bcast_name_and_code;

    le_audio_config_callback_configs->GetBroadcastNameAndEncryptionCode(&bcast_name_and_code);
    audio_configuration->broadcast_source_name = bcast_name_and_code.broadcast_source_name;
    audio_configuration->broadcast_source_name_len = bcast_name_and_code.broadcast_source_name_len;
    audio_configuration->broadcast_code = bcast_name_and_code.broadcast_code;

    audio_configuration->broadcast_id = le_audio_config_callback_configs->GetBroadcastId();

    leAudioClient_GetBcastConfig(audio_configuration);

    return audio_configuration;
}

void leAudioClient_GetBroadcastAdvConfig(CapClientBcastSrcAdvParams *bcast_adv_settings)
{
    CapClientBcastSrcAdvParams *bcast_adv_params;

    le_audio_config_callback_configs->GetBroadcastAdvParams(&bcast_adv_params);

    bcast_adv_settings->advEventProperties = bcast_adv_params->advEventProperties;
    bcast_adv_settings->advIntervalMin = bcast_adv_params->advIntervalMin;
    bcast_adv_settings->advIntervalMax = bcast_adv_params->advIntervalMax;
    bcast_adv_settings->primaryAdvPhy = bcast_adv_params->primaryAdvPhy;
    bcast_adv_settings->primaryAdvChannelMap = bcast_adv_params->primaryAdvChannelMap;
    bcast_adv_settings->secondaryAdvMaxSkip = bcast_adv_params->secondaryAdvMaxSkip;
    bcast_adv_settings->secondaryAdvPhy = bcast_adv_params->secondaryAdvPhy;
    bcast_adv_settings->advSid = bcast_adv_params->advSid;
    bcast_adv_settings->periodicAdvIntervalMin = bcast_adv_params->periodicAdvIntervalMin;
    bcast_adv_settings->periodicAdvIntervalMax = bcast_adv_params->periodicAdvIntervalMax;
    bcast_adv_settings->advertisingTransmitPower = bcast_adv_params->advertisingTransmitPower;
}

void leAudioClientBroadcast_VerifyClientRegistration(void)
{
    /* Ensure needed callbacks are registered by the application */
    PanicNull((void *)le_audio_config_callback_configs);
    PanicFalse(le_audio_config_callback_configs->GetBroadcastNameAndEncryptionCode != NULL);
    PanicFalse(le_audio_config_callback_configs->GetBroadcastAdvParams != NULL);
    PanicFalse(le_audio_config_callback_configs->GetBroadcastId != NULL);
    PanicFalse(le_audio_config_callback_configs->GetBroadcastAudioConfig != NULL || 
                le_audio_config_callback_configs->GetBroadcastAudioConfigV2 != NULL);
}

void leAudioClient_SetBroadcastAudioConfigType(le_audio_client_broadcast_config_type_t config_type)
{
    lea_client_bcast_config.config_type = config_type;
}

void LeAudioClient_RegisterConfigInterface(const le_audio_client_config_interface_t * lea_audio_config)
{
    PanicNull((void *)lea_audio_config);

    le_audio_config_callback_configs = lea_audio_config;
}

#endif /* INCLUDE_LE_AUDIO_BROADCAST_SOURCE */
